package Chat;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ChatServer extends UnicastRemoteObject implements ChatService {

	private static final long serialVersionUID = 1L;

	private List<String> clientListe = new CopyOnWriteArrayList<String>();

	public ChatServer() throws RemoteException {
		super();
		//Erstellung der Registry
		LocateRegistry.createRegistry(Registry.REGISTRY_PORT);

		try {
			//Registrierung des Remote-Objektes mit Übergabe seines Namens als URL
			Naming.rebind("rmi://localhost/server", this);
		} catch (MalformedURLException e) {
			System.out.println("(Re)bind fehlgeschlagen.");
			e.printStackTrace();
		}

		System.out.println("Server started.");
	}

	public void login(String s) throws RemoteException {
		this.clientListe.add(s);
		System.out.println("User '" + s + "' logged in.");
	}

	//Aufheben des Binding, wenn Nutzer sich ausloggt/ausgeloggt wird
	public void logout(String s) throws RemoteException {
		this.clientListe.remove(s);
		System.out.println("User '" + s + "' logged out.");
		try {
			Naming.unbind(s);
		} catch (RemoteException | MalformedURLException | NotBoundException e) {
			e.printStackTrace();
		}
	}

	//Methode, um etwas an den Server zu senden
	public void send(String s) throws RemoteException {
		ClientService client = null;
		for (String name : this.clientListe) {
			try {
				//Referenz auf das Objekt in der Registry holen
				client = (ClientService) Naming.lookup("//localhost/" + name);
			} catch (MalformedURLException | RemoteException | NotBoundException e) {
				// Wenn Client nicht erreichbar -> logout
				logout(s);
			}
			//Weitersendung der Nachricht an den Client
			try {
				client.send(s);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}

	// Kann z.B. genutzt werden, um UserListe im ChatClient anzuzeigen
	// -> Steht aber nicht in der Aufgabenstellung, daher laut Manuel ok
	// wenn wir UserList nicht im Client anzeigen und die Methode nicht nutzen
	// -> Führt nicht zu Punkteabzug laut Manuel und Jens!
	public List<String> getUserList() throws RemoteException {
		return this.clientListe;
	}

}
